﻿/*
 * 原型模式，用原型实例只想创建对象的种类，并且通过拷贝这些原型创建新的对象
 * 原型模式就是从一个对象再创建另一个可定制的对象，而且不需要知道任何创建的细节
 * 
 * 
 * 浅复制 只针对值类型进行复制，对于引用类型是复制指向引用类型的地址
 * 深复制，针对对象本身，当对一个对象进行深度复制时，除了复制值类型，他还会把引用对象的变量指向复制过来的新对象，而不是浅复制里的只复制引用地址
 * 
 */
//浅复制
clonePrototype clone = new clonePrototype("大海");
    clonePrototype clone1 = (clonePrototype)clone.Clone();
    Console.WriteLine(clone1.name);
//深复制
JL a = new JL("dahai");
a.setwork("111","222");
a.display();
var b = a.Clone() as JL;
b.setwork("333","444");
b.display();    
var c = b.Clone() as JL;
c.setwork("555","666");
c.display();

#region 浅复制
abstract class Prototype
{
    private string _name;
    public string name { get { return _name; } }

    public Prototype(string name)
    {
        this._name = name;
    }
    public abstract Prototype Clone();
}

class clonePrototype : Prototype
{

    public clonePrototype(string name) : base(name) { }
    public override Prototype Clone()
    {
        //创建当前对象的浅拷贝副本
        return (Prototype)this.MemberwiseClone();
        /*
         * 如果字段是值类型的，就对该字段进行逐位复制，如果字段是引用类型的，则复制引用但不复制应用的对象，英寸原始对象机器副本应勇同一对象
         */
    }
}
#endregion

#region 深复制
/// <summary>
/// 工作
/// </summary>
class work : ICloneable
{
    public work() { }


    public string addess { get; set; }

    public string wkname { get; set; }

    /// <summary>
    /// 复制
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public object Clone()
    {
        return this.MemberwiseClone() as object;
    }
}

class JL : ICloneable
{
    public string name { get; set; }
    private work work;
   public JL(string name) 
    { 
        this.name = name;
        this.work = new work();
 
    }

    public JL(work _work) 
    {
    this.work  = _work.Clone() as work;
    }

    public void setwork(string addess, string wkname)
    {
        this.work.addess = addess;
        this.work.wkname = wkname;
    }
    public void display()
    {
        Console.WriteLine(this.work.addess + this.work.wkname);
    }

    public object Clone()
    {
        JL jL = new JL(this.work);
        jL.name = this.name;
        return jL;
    }
}


#endregion
